\begin{tikzpicture}

	\definecolor{appcolor}        {rgb}{1,1,0.7}
	\definecolor{defaultcolor}    {rgb}{1,1,1}
	\definecolor{drivercolor}     {rgb}{0.6,0.7,0.8}

	\tikzstyle{treenode} = [component, path fading=flow fade, align=center,
	                        rounded corners=1, minimum height=6ex]

	\tikzstyle{service} = [draw=black, draw opacity=0.4, ball color=defaultcolor, fill opacity=0.2,
	                       rounded corners=0, shape=semicircle,
	                       inner sep=1.3ex, outer sep=0, above]

	\tikzstyle{appnode}    = [treenode, bottom color=appcolor]
	\tikzstyle{drivernode} = [treenode, bottom color=drivercolor]

	%
	% Components
	%

	\coordinate (anchor);

	% platform driver
	\node[drivernode, minimum width=26ex, at=(anchor)] (platformdrv) {Platform Driver};
	\path (platformdrv.north) node[service, scale=0.4] (platformservice) {};
	\path (platformdrv.north) node[scale=0.7, yshift=-1.5ex] {Platform};

	% NIC router
	\node[treenode, minimum width=26ex, right=4ex of platformdrv] (nicrouter)  {NIC Router};
	\path (nicrouter.160) node[service, scale=0.4] (uplinkservice) {};
	\path (uplinkservice) node[scale=0.7, yshift=-2ex] {Uplink};
	\path (nicrouter.20) node[service, scale=0.4] (nicservice) {};
	\path (nicservice) node[scale=0.7, yshift=-2ex] {NIC};

	% USB host driver
	\node[drivernode, minimum width=26ex, above=4ex of platformdrv] (usbdrv)  {USB Host Driver};
	\path (usbdrv.north) node[service, scale=0.4] (usbservice) {};
	\path (usbservice) node[scale=0.7, yshift=-2ex] {USB};

	% USB modem driver
	\node[drivernode, minimum width=26ex, above=4ex of usbdrv] (modemdrv)  {USB Modem Driver};
	\path (modemdrv.north) node[service, scale=0.4] (terminalservice) {};
	\path (terminalservice) node[scale=0.7, yshift=-2ex] {Terminal};

	% MBIM CLI
	\node[treenode, minimum width=26ex, above=8ex of modemdrv] (mbimcli)  {MBIM CLI};

	% app
	\node[appnode, minimum width=26ex, minimum height=12ex, above=24ex of nicservice, xshift=20ex] (nicapp) {};
	\path (nicapp.north)+(0,-3ex) node {Network Application};

	\node[draw, draw opacity=0.2, fill=black, fill opacity=0.1,
	      text opacity=1, rounded corners=2, anchor=south, at=(nicapp.south),
	      yshift=1ex] (tcpip) {TCP/IP Stack};

	\node[scale=0.7, at=(tcpip.north), anchor=south] {Socket API};

	% config / state information flow
	\tikzstyle{infoflow} = [opacity=0.5,
	                        decoration={markings,
	                        mark=between positions 0.03 and 1 step 1ex with {\arrow{latex}}},
	                        postaction={decorate}]

	\path[infoflow] (mbimcli)+(0,5ex) -- node[pos=-0.5] {SIM PIN} (mbimcli.center);

	\path[infoflow] (mbimcli.east)
		.. controls +(15ex,0) and +(0ex,10ex) ..
		   coordinate[pos=0.3] (annotation) node[right] {config} (nicrouter.center);

	%
	% Sessions
	%
	\tikzstyle{treesessionarrow} = [arrow, thick]
	\path[treesessionarrow] (tcpip) .. controls +(0,-10ex) and +(0,10ex) .. (nicservice);
	\path[treesessionarrow] (platformservice |- usbdrv.south) -- (platformservice);
	\path[treesessionarrow] (modemdrv) -- (usbservice);
	\path[treesessionarrow] (mbimcli) -- coordinate (mbimprot) (terminalservice);
	\path[treesessionarrow] (modemdrv.345) .. controls +(0,-3ex) and +(0,5ex) .. (uplinkservice);

	%
	% Annotations
	%
	\tikzstyle{details} = [rectangle callout, draw opacity=0.3, fill=white, fill opacity=0.2,
	                       text opacity=0.5, rounded corners=2, draw]

	\path (annotation)+(3ex,3ex)
		node [details, anchor=south west, callout relative pointer={(-3ex,-3ex)}, align=left] {
		IP address\\
		Netmask\\
		Gateway\\
		DNS server
		};

	\path (mbimprot)+(3ex,0ex)
		node [details, minimum height=5ex, anchor=west, callout relative pointer={(-3ex,-0.5ex)}, align=left] {
		Modem protocol
		};

\end{tikzpicture}
